package com.lonely.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.api.mes.model.dto.SynchronizedUserDTO;
import com.lonely.api.mes.service.ISynchronizedMesService;
import com.lonely.common.core.domain.BaseEntity;
import com.lonely.common.core.domain.Select;
import com.lonely.common.core.domain.auth.UserMsgDto;
import com.lonely.common.core.page.Condition;
import com.lonely.common.enums.DataScope;
import com.lonely.common.enums.UserStatus;
import com.lonely.common.threadlocals.DataPermissionThreadLocal;
import com.lonely.common.utils.JsonUtil;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.system.domain.dto.user.SysUserPageQueryDto;
import com.lonely.system.domain.dto.user.SysUserRoleNameDto;
import com.lonely.system.domain.dto.user.SysUserSubmitDto;
import com.lonely.system.domain.dto.user.UpdateUserPasswordDTO;
import com.lonely.system.domain.entity.SysFactory;
import com.lonely.system.domain.entity.SysProductionLine;
import com.lonely.system.domain.entity.SysUser;
import com.lonely.system.domain.vo.system.user.SysUserDetailVo;
import com.lonely.system.domain.vo.system.user.SysUserPageQueryVo;
import com.lonely.system.enums.SysProductionLineEnum;
import com.lonely.system.mapper.SysUserMapper;
import com.lonely.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户 业务层处理
 *
 * @author fzzf
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {


    @Autowired
    private ISysFactoryService sysFactoryService;

    @Autowired
    private ISysProductionLineService sysProductionLineService;

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @Autowired
    private ISysDataPermissionsService sysDataPermissionsService;

    @Autowired
    private ISynchronizedMesService synchronizedMesService;

    /**
     * 分页查询
     *
     * @param queryDto
     * @return
     */
    @Override
    public Page<SysUserPageQueryVo> page(SysUserPageQueryDto queryDto) {
        Page<SysUser> page = Condition.page(queryDto);
//        QueryWrapper<SysUser> queryWrapper = Condition.getQueryWrapper(BeanUtil.beanToMap(queryDto), SysUser.class);
//        Page<SysUser> userPage = super.page(page, queryWrapper);

        IPage<SysUser> userPage = super.getBaseMapper().page(page, queryDto);

        Page<SysUserPageQueryVo> resultPage = new Page<>();
        BeanUtils.copyProperties(userPage, resultPage);
        if (CollUtil.isNotEmpty(userPage.getRecords())) {
            // 工厂id和名称映射
            List<Long> factoryIds = userPage.getRecords().stream().map(SysUser::getFactoryId).distinct().collect(Collectors.toList());
            Map<Long, String> factoryNameMap = Optional.ofNullable(this.sysFactoryService.listByIds(factoryIds)).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(BaseEntity::getId, SysFactory::getName));

            // 产线id和名称映射
            List<Long> plIds = userPage.getRecords().stream().map(SysUser::getProductionLineId).distinct().collect(Collectors.toList());
            Map<Long, String> plNameMap = Optional.ofNullable(this.sysProductionLineService.listByIds(plIds)).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(BaseEntity::getId, SysProductionLine::getName));

            // 用户角色列表映射
            List<Long> userIds = userPage.getRecords().stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
            Map<Long, String> userRoleNamesMap = Optional.ofNullable(this.sysUserRoleService.queryUserRoleNames(userIds)).orElse(new ArrayList<>())
                    .stream().collect(Collectors.groupingBy(SysUserRoleNameDto::getUserId, Collectors.mapping(SysUserRoleNameDto::getRoleName, Collectors.joining("|"))));

            resultPage.setRecords(userPage.getRecords().stream().map(x -> {
                SysUserPageQueryVo userPageQueryVo = new SysUserPageQueryVo();
                BeanUtils.copyProperties(x, userPageQueryVo);

                // 手机号脱敏操作
                userPageQueryVo.setPhone(DesensitizedUtil.mobilePhone(x.getPhone()));

                // 设置所属组织
                String factoryName = MapUtil.getStr(factoryNameMap, x.getFactoryId(), "未知");
                String plName = MapUtil.getStr(plNameMap, x.getProductionLineId(), "未知");
                userPageQueryVo.setBelongingOrganization(String.format("%s-%s", factoryName, plName));

                // 设置角色信息
                userPageQueryVo.setRoleNames(MapUtil.getStr(userRoleNamesMap, x.getId(), ""));

                return userPageQueryVo;
            }).collect(Collectors.toList()));
        }
        return resultPage;
    }

    /**
     * 创建用户信息
     *
     * @param submitDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(SysUserSubmitDto submitDto) {
        Assert.isNull(submitDto.getId(), "参数错误(id)");

        // 判断工厂名称是否已存在
        checkUserInfo(submitDto);

        // 入库
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(submitDto, sysUser);
        sysUser.setNickName(submitDto.getUserName());
        sysUser.setPositionTag(JsonUtil.toJsonString(submitDto.getPositionTags()));
        sysUser.setCreateBy(SecurityUtils.getUserId());
        sysUser.setUpdateBy(SecurityUtils.getUserId());
        super.save(sysUser);

        // 同步员工信息
        SynchronizedUserDTO synchronizedUserDTO = this.generatorAddUserDTO(sysUser);
        this.synchronizedMesService.staffSynchronized(synchronizedUserDTO);
    }


    /**
     * 更新用户信息
     *
     * @param submitDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysUserSubmitDto submitDto) {
        Assert.notNull(submitDto.getId(), "参数错误(id)");

        // 判断工厂名称是否已存在
        checkUserInfo(submitDto);

        SysUser oldUser = super.getById(submitDto.getId());
        BeanUtils.copyProperties(submitDto, oldUser);
        oldUser.setNickName(submitDto.getUserName());
        oldUser.setPositionTag(JSON.toJSONString(submitDto.getPositionTags()));
        oldUser.setCreateBy(SecurityUtils.getUserId());
        oldUser.setUpdateBy(SecurityUtils.getUserId());
        super.updateById(oldUser);

        // 同步员工信息
        SynchronizedUserDTO synchronizedUserDTO = this.generatorAddUserDTO(oldUser);
        this.synchronizedMesService.staffSynchronized(synchronizedUserDTO);
    }

    /**
     * 根据用户ID查询用户名称
     *
     * @param userId
     * @return
     */
    @Override
    public String getUserNameById(Long userId) {
        Assert.notNull(userId, "用户id为空");
        SysUser user = super.getById(userId);
        Assert.notNull(user, "该用户不存在");
        return user.getUserName();
    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     */
    @Override
    public SysUserDetailVo detail(Long userId) {
        // 构建用户信息
        SysUser user = super.getById(userId);
        Assert.notNull(user, "该用户不存在");

        SysUserDetailVo userDetailVo = new SysUserDetailVo();

        // 设置用户信息
        SysUserDetailVo.UserInfo userInfo = new SysUserDetailVo.UserInfo();
        BeanUtils.copyProperties(user, userInfo);
        userInfo.setUserStatus(user.getStatus());
        userInfo.setPositionTags(StrUtil.isNotBlank(user.getPositionTag()) ?
                JSON.parseArray(user.getPositionTag(), String.class) : new ArrayList<>());
        userDetailVo.setUserInfo(userInfo);

        // 获取用户角色信息
        List<SysUserDetailVo.RoleInfo> rolesByUserId = this.sysUserRoleService.getRolesByUserId(userId);
        userDetailVo.setAllotRoleList(rolesByUserId);

        // 获取用户数据权限信息
        SysUserDetailVo.OrganizationInfo organization = this.sysDataPermissionsService.getOrganizationsByUserId(userId);
        userDetailVo.setAllotOrganization(organization);

        return userDetailVo;
    }

    /**
     * 用户信息转换成 接口对象
     *
     * @param sysUser
     * @return
     */
    private SynchronizedUserDTO generatorAddUserDTO(SysUser sysUser) {
        SynchronizedUserDTO synchronizedUserDTO = new SynchronizedUserDTO();
        List<SynchronizedUserDTO.UserInfo> users = new ArrayList<>();
        SynchronizedUserDTO.UserInfo userInfo = new SynchronizedUserDTO.UserInfo();
        userInfo.setBcofwk("staff");
        userInfo.setFirstname(sysUser.getUserName());
        userInfo.setGender(sysUser.getSex() == 1 ? "0" : "1");
        userInfo.setLeave(sysUser.getStatus() == UserStatus.RESIGN.getCode() ? "1" : "0");
        userInfo.setUserno(Convert.toStr(sysUser.getId()));
        userInfo.setCellphone(sysUser.getPhone());
        userInfo.setEmailaddress(null);
        userInfo.setFirstOrgCode(null);
        userInfo.setLoginname(null);
        userInfo.setUserCardno(null);
        userInfo.setWorkshoCd(null);
        users.add(userInfo);
        synchronizedUserDTO.setUsers(users);
        return synchronizedUserDTO;
    }


    /**
     * 校验用户信息
     *
     * @param submitDto
     */
    private void checkUserInfo(SysUserSubmitDto submitDto) {

        //1. 校验用户是否号是否已注册
        int count = super.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, submitDto.getPhone())
                .eq(SysUser::getFactoryId, submitDto.getFactoryId())
                .eq(SysUser::getProductionLineId, submitDto.getProductionLineId())
                .ne(submitDto.getId() != null, SysUser::getId, submitDto.getId()));
        Assert.isTrue(count == 0, "该手机号已注册");

        //2. 检验用户id对应的数据是否存在
        if (submitDto.getId() != null) {
            SysUser oldUser = super.getById(submitDto.getId());
            Assert.notNull(oldUser, "该用户不存在");
            Assert.isTrue(Objects.equals(UserStatus.ENABLED.getCode(), oldUser.getStatus()), "该用户已停用");
        }

        //3. 校验工厂id是否存在
        SysFactory factory = this.sysFactoryService.getById(submitDto.getFactoryId());
        Assert.notNull(factory, "工厂不存在");

        // 校验产线id是否存在
        int plCount = this.sysProductionLineService.count(new LambdaQueryWrapper<SysProductionLine>().eq(SysProductionLine::getFactoryId, submitDto.getFactoryId())
                .eq(SysProductionLine::getId, submitDto.getProductionLineId()));
        Assert.isTrue(plCount == 1, "该产线不存在");

        // 新增场景需要校验密码是否为空
        if (submitDto.getId() == null) {
            Assert.notNull(submitDto.getPassword(), "密码不能为空");
        }

    }


    /**
     * 通过用户名查询用户
     *
     * @param userId 用户名
     * @return 用户对象信息
     */
    @Override
    public UserMsgDto selectUserByUserId(Long userId) {
        SysUser sysUser = super.getById(userId);
        Assert.notNull(sysUser, "用户不存在");

        UserMsgDto userMsgDto = new UserMsgDto();
        BeanUtils.copyProperties(sysUser, userMsgDto);
        userMsgDto.setUserId(sysUser.getId());
        return userMsgDto;
//        return userMapper.selectUserByUserName(userName);
    }

    /**
     * 显示指定用户的手机号码
     *
     * @param userId
     * @return
     */
    @Override
    public String getDeclarePhone(Long userId) {
        SysUser user = super.getById(userId);
        Assert.notNull(user, "用户不存在");
        return user.getPhone();
    }

    /**
     * 离职
     *
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resign(Long userId) {
        SysUser user = super.getById(userId);
        Assert.notNull(user, "用户不存在");
        if (!Objects.equals(user.getStatus(), UserStatus.RESIGN.getCode())) {
            user.setStatus(UserStatus.RESIGN.getCode());
            user.setUpdateBy(SecurityUtils.getUserId());
            super.updateById(user);

            // 同步员工信息
            SynchronizedUserDTO synchronizedUserDTO = this.generatorAddUserDTO(user);
            this.synchronizedMesService.staffSynchronized(synchronizedUserDTO);
        }
    }

    /**
     * 启用
     *
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enabled(Long userId) {
        SysUser user = super.getById(userId);
        Assert.notNull(user, "用户不存在");
        if (Objects.equals(user.getStatus(), UserStatus.DISABLE.getCode())) {
            user.setStatus(UserStatus.ENABLED.getCode());
            user.setUpdateBy(SecurityUtils.getUserId());
            super.updateById(user);

            // 同步员工信息
            SynchronizedUserDTO synchronizedUserDTO = this.generatorAddUserDTO(user);
            this.synchronizedMesService.staffSynchronized(synchronizedUserDTO);
        }
    }

    /**
     * 停用
     *
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disabled(Long userId) {
        SysUser user = super.getById(userId);
        Assert.notNull(user, "用户不存在");
        if (Objects.equals(user.getStatus(), UserStatus.ENABLED.getCode())) {
            user.setStatus(UserStatus.DISABLE.getCode());
            user.setUpdateBy(SecurityUtils.getUserId());
            super.updateById(user);

            // 同步员工信息
            SynchronizedUserDTO synchronizedUserDTO = this.generatorAddUserDTO(user);
            this.synchronizedMesService.staffSynchronized(synchronizedUserDTO);
        }
    }

    /**
     * 获取当前登录用户对应产线的跟单员列表
     *
     * @return
     */
    @Override
    public List<Select> getMerchandiserSelectOptions() {
        return super.getBaseMapper().getMerchandiserSelectOptions(SecurityUtils.getFactoryId());
    }

    /**
     * 获取当前登录用户对应产线的设计师列表
     *
     * @return
     */
    @Override
    public List<Select> getDesignerSelectOptions() {
        return super.getBaseMapper().getDesignerSelectOptions(SecurityUtils.getFactoryId());
    }

    /**
     * 获取当前登录用户对应有权限的生产工种为裁剪的列表
     *
     * @return
     */
    @Override
    public List<Select> getCuttingBedEmployeeSelectOptions() {
        DataPermissionThreadLocal.setDataPermission(DataScope.FACTORY, "factory_id");
        return super.list(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getWorkType, SysProductionLineEnum.WorkTypeEnum.CUT_OUT.workType)
                .eq(SysUser::getStatus, UserStatus.ENABLED.getCode())
        ).stream().map(user -> {
            Select select = new Select();
            select.setValue(Convert.toStr(user.getId()));
            select.setLabel(user.getUserName());
            return select;
        }).collect(Collectors.toList());
    }

    /**
     * 修改密码
     *
     * @param requestDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(UpdateUserPasswordDTO requestDto) {
        // 验证老密码是否正确
        SysUser user = super.getById(requestDto.getUserId());
        Assert.notNull(user, "用户不存在");
        Assert.isTrue(StrUtil.equals(user.getPassword(), requestDto.getOldPassword()), "旧密码错误");

        user.setPassword(requestDto.getNewPassword());
        user.setUpdateBy(SecurityUtils.getUserId());
        super.updateById(user);
    }


    /*****************************************************************************/


//    /**
//     * 根据条件分页查询用户列表
//     *
//     * @param user 用户信息
//     * @return 用户信息集合信息
//     */
//    @Override
//    @DataScope(deptAlias = "d", userAlias = "u")
//    public List<SysUser> selectUserList(SysUser user) {
//        return userMapper.selectUserList(user);
//    }
//
//
//    /**
//     * 通过用户ID查询用户
//     *
//     * @param userId 用户ID
//     * @return 用户对象信息
//     */
//    @Override
//    public SysUser selectUserById(Long userId) {
//        return userMapper.selectUserById(userId);
//    }
//
//    /**
//     * 查询用户所属角色组
//     *
//     * @param userName 用户名
//     * @return 结果
//     */
//    @Override
//    public String selectUserRoleGroup(String userName) {
//        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
//        StringBuffer idsStr = new StringBuffer();
//        for (SysRole role : list) {
//            idsStr.append(role.getRoleName()).append(",");
//        }
//        if (StringUtils.isNotEmpty(idsStr.toString())) {
//            return idsStr.substring(0, idsStr.length() - 1);
//        }
//        return idsStr.toString();
//    }
//
//    /**
//     * 查询用户所属岗位组
//     *
//     * @param userName 用户名
//     * @return 结果
//     */
//    @Override
//    public String selectUserPostGroup(String userName) {
//        List<SysPost> list = postMapper.selectPostsByUserName(userName);
//        StringBuffer idsStr = new StringBuffer();
//        for (SysPost post : list) {
//            idsStr.append(post.getPostName()).append(",");
//        }
//        if (StringUtils.isNotEmpty(idsStr.toString())) {
//            return idsStr.substring(0, idsStr.length() - 1);
//        }
//        return idsStr.toString();
//    }
//
//    /**
//     * 校验用户名称是否唯一
//     *
//     * @param userName 用户名称
//     * @return 结果
//     */
//    @Override
//    public String checkUserNameUnique(String userName) {
//        int count = userMapper.checkUserNameUnique(userName);
//        if (count > 0) {
//            return UserConstants.NOT_UNIQUE;
//        }
//        return UserConstants.UNIQUE;
//    }
//
//    /**
//     * 校验用户名称是否唯一
//     *
//     * @param user 用户信息
//     * @return
//     */
//    @Override
//    public String checkPhoneUnique(SysUser user) {
//        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
//        SysUser info = userMapper.checkPhoneUnique(user.getPhone());
//        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue()) {
//            return UserConstants.NOT_UNIQUE;
//        }
//        return UserConstants.UNIQUE;
//    }


//    /**
//     * 新增保存用户信息
//     *
//     * @param user 用户信息
//     * @return 结果
//     */
//    @Override
//    @Transactional
//    public int insertUser(SysUser user) {
//        // 新增用户信息
//        int rows = userMapper.insertUser(user);
//        // 新增用户岗位关联
//        insertUserPost(user);
//        // 新增用户与角色管理
//        insertUserRole(user);
//        return rows;
//    }
//
//    /**
//     * 修改保存用户信息
//     *
//     * @param user 用户信息
//     * @return 结果
//     */
//    @Override
//    @Transactional
//    public int updateUser(SysUser user) {
//        Long userId = user.getId();
//        // 删除用户与角色关联
//        userRoleMapper.deleteUserRoleByUserId(userId);
//        // 新增用户与角色管理
//        insertUserRole(user);
//        // 删除用户与岗位关联
//        userPostMapper.deleteUserPostByUserId(userId);
//        // 新增用户与岗位管理
//        insertUserPost(user);
//        return userMapper.updateUser(user);
//    }
//
//    /**
//     * 修改用户状态
//     *
//     * @param user 用户信息
//     * @return 结果
//     */
//    @Override
//    public int updateUserStatus(SysUser user) {
//        return userMapper.updateUser(user);
//    }
//
//    /**
//     * 修改用户基本信息
//     *
//     * @param user 用户信息
//     * @return 结果
//     */
//    @Override
//    public int updateUserProfile(SysUser user) {
//        return userMapper.updateUser(user);
//    }
//
//    /**
//     * 修改用户头像
//     *
//     * @param userName 用户名
//     * @param avatar   头像地址
//     * @return 结果
//     */
//    @Override
//    public boolean updateUserAvatar(String userName, String avatar) {
//        return userMapper.updateUserAvatar(userName, avatar) > 0;
//    }
//
//    /**
//     * 重置用户密码
//     *
//     * @param user 用户信息
//     * @return 结果
//     */
//    @Override
//    public int resetPwd(SysUser user) {
//        return userMapper.updateUser(user);
//    }
//
//    /**
//     * 重置用户密码
//     *
//     * @param userName 用户名
//     * @param password 密码
//     * @return 结果
//     */
//    @Override
//    public int resetUserPwd(String userName, String password) {
//        return userMapper.resetUserPwd(userName, password);
//    }
//
}
